#ifndef GLHANDLE_H
#define GLHANDLE_H
class GLHandler : public Handler 
{
public:
	GLHandler(GLView * glView, Model * model):glView(glView),is_create(false), model (model){}
	~GLHandler(){}

public:
	int lButtonDown(WPARAM state, int x, int y)
	{
		//::MessageBox(0, L"Draw.", L"Error", MB_ICONEXCLAMATION | MB_OK);
		model->setMousePos(model->cullingView, x, y);
		if(state == MK_LBUTTON)
		{
			model->setMouseLeft(model->cullingView, true);
		}
		return 0;
	}
	int lButtonUp(WPARAM state, int x, int y)
	{

		::SetFocus(this->handle);
		
		model->setMousePos(model->cullingView, x, y);
		model->setMouseLeft(model->cullingView, false);
		
		if (model->cullingView.viewMode == EDIT)
		{
			EnterCriticalSection(&CriticalSection); 
			//model->partialUpdate = true; 
			model->paintUpdate = true ;
			model->brush_paint();
			LeaveCriticalSection(&CriticalSection); 
			model->setUpdated(model->cullingView, true);
			model->setUpdated(model->mappingView, true);
		}
		
		return 0;
	}
	int rButtonDown(WPARAM state, int x, int y)
	{
		model->setMousePos(model->cullingView, x, y);
		if(state == MK_RBUTTON)
		{
			model->setMouseRight(model->cullingView, true);
		}
		return 0;		
	}
	/*
	This is for pick face 
	int rButtonUp(WPARAM state, int x, int y)
	{
		model->setMousePos(model->cullingView, x, y);
		model->setMouseRight(model->cullingView, false);
		if (model->cullingView.viewMode == EDIT)
		{
			model->pick_face();
			model->setUpdated(model->cullingView, true);
			model->setUpdated(model->mappingView, true);
			//model->setUpdated(true);
		}
		return 0;
	}
	*/
	// this is for pick edge
	int rButtonUp(WPARAM state, int x, int y)
	{
		model->setMousePos(model->cullingView, x, y);
		model->setMouseRight(model->cullingView, false);
		if (model->cullingView.viewMode == EDIT)
		{
			if (model->selectMode)
			{
				model->pick_face();
			}
			else	
			{
				model->pick_edge(); 
			}
			model->setUpdated(model->cullingView, true);
			model->setUpdated(model->mappingView, true);
			//model->setUpdated(true);
		}
		return 0;
	}
	int mouseMove(WPARAM state, int x, int y)
	{
		//model->moveBrush(model->cullingView, x, y);
		//model->setUpdated(model->cullingView, true);
		::SetFocus(this->handle);

		POINT pt;
		::GetCursorPos(&pt);
		::ScreenToClient(this->handle, &pt);
		x = pt.x ;
		y = pt.y ;

		if (model->cullingView.viewMode == VIEW)
		{
			if(state == MK_LBUTTON)
			{
				if (model->getMouseLeft(model->cullingView) )
				{	
					model->rotateCamera(model->cullingView, x, y);
					EnterCriticalSection(&CriticalSection); 
					model->setUpdated(model->cullingView, true);
					model->setUpdated(model->mappingView, true);
					model->cullingState = true ;
					LeaveCriticalSection(&CriticalSection); 
				}
			}
			if(state == MK_RBUTTON)
			{
				if (model->getMouseRight(model->cullingView))
				{
					model->zoomCamera(model->cullingView, y);
					//model->zoomCamera(model->mappingView, y);
					model->mappingView.cameraDis = model->cullingView.cameraDis ;
					EnterCriticalSection(&CriticalSection); 
					model->setUpdated(model->cullingView, true);
					model->setUpdated(model->mappingView, true);
					model->cullingState = true ;
					LeaveCriticalSection(&CriticalSection); 
				}
			}
		}
		else if (model->cullingView.viewMode == EDIT)
		{
			
			//if (model->getMouseLeft(model->cullingView))
			//{
			/*
				EnterCriticalSection(&CriticalSection); 
				model->paint();
				model->movePerpBrush(model->cullingView, x, y);
				model->setUpdated(model->cullingView, true);
				model->setUpdated(model->mappingView, true);
				LeaveCriticalSection(&CriticalSection); 
				*/
			//}
			//else
			//{
				
				EnterCriticalSection(&CriticalSection); 
				model->moveBrush(model->cullingView, x, y);
				model->partialUpdate = true ;
				model->cullingState = true ;
				model->draw_perspective();
				model->setUpdated(model->cullingView, true);
				model->setUpdated(model->mappingView, true);								
				
				LeaveCriticalSection(&CriticalSection); 
			//}
			
		}

		return 0;
	}

	int create() 
	{
		
		return 0;
	}
	int size(int w, int h, WPARAM type)
	{
		//model->setUpdated(model->cullingView, true);
		//model->setWindowSize(model->cullingView, w, h);
		return 0; 
	}
	int timer(WPARAM id, LPARAM lParam)
	{
		//glView->Draw();
		return 0;
	}
	int paint()
	{
		
		if (!is_create)
		{
			glView->EnableOpenGL();
			//model->init();
			model->setUpdated(model->cullingView, true);
			model->setUpdated(model->mappingView, true);
			is_create = true;
		}
		else
		{
			model->setUpdated(model->cullingView, true);
			model->setUpdated(model->mappingView, true);
		}
		return 0;
	}
	int destroy()
	{
		// close OpenGL Rendering context
		
	    glView->DisableOpenGL();
		::DestroyWindow(handle);
		return 0;
	}
	int keyUp(int key, LPARAM lParam)
	{
		switch (key)
		{
		case VK_TAB:
			if (model->mappingView.viewMode == EDIT)
			{
				model->mappingView.viewMode = VIEW ;
				model->cullingView.viewMode = VIEW ;
				model->mappingView.lbf = TRANSLATE ;
				//model->cullingView.lbf = TRANSLATE ;

			} else
			{
				model->mappingView.viewMode = EDIT ;
				model->cullingView.viewMode = EDIT ;
				model->mappingView.lbf = PAINT ;
			}
			model->mappingView.updated = true;
			model->cullingView.updated = true;
			break;
		case 0x52 : //Key R
			//model->mappingView.lbf = ROTATE ;
			model->mappingView.cameraAglY+=5 ;
			model->mappingView.updated = true;
			break;
		case 0x53 : // Key S // change the select mode ;
			model->selectMode = ! model->selectMode ;
			break; 
		case 0x54 : //Key T
			//model->mappingView.lbf = TRANSLATE ;
			model->mappingView.cameraAglY-=5 ;
			model->mappingView.updated = true;
			break;
		case 0x55 : //Key U upsampling ;
			if (model->mappingView.viewMode == EDIT)
			{
				model->upSampling () ;
				model->mappingView.updated = true;
				model->cullingView.updated = true;
			}
			break;
		case 0x44 : //Key D downsampling ;
			if (model->mappingView.viewMode == EDIT)
			{
				model->downSampling ();
				model->mappingView.updated = true; 
				model->cullingView.updated = true;
			}
			break;

		case 'B' :  // key B downsampling ;
			model->blenderLayer = !model->blenderLayer; 
			model->setBlenderFlag(model->blenderLayer );
			model->mappingView.updated = true; 
			model->cullingView.updated = true;
			break;

		case '1' : // Select Layer 0;
			model->setActiveLayer(1); 
			model->mappingView.updated = true; 
			model->cullingView.updated = true;
			break ;
		case '2' : // Select Layer 0;
			model->setActiveLayer(2); 
			model->mappingView.updated = true; 
			model->cullingView.updated = true;
			break ;
		default :
			;
		}
		return 0;
	}
	int command(int id, int cmd, LPARAM msg)
	{ 
		return 0;
	}
protected:
	GLView * glView ;
	Model * model ;
	bool is_create ;
};

#endif